package com.fintech.pangu.security.authentication.filter;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 处理 POST /api/login 的认证Filter
 * 目前大致逻辑同 UsernamePasswordAuthenticationFilter，后续再调整
 */
@Slf4j
public class ApiLoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    private String usernameParameter = "username";
    private String passwordParameter = "password";

    public ApiLoginAuthenticationFilter(){
        super(new AntPathRequestMatcher("/api/login", "POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {

        Map<String,String> requestBodyParametersMap = getRequestBodyJsonParameters(request);
        String username = requestBodyParametersMap.get(usernameParameter);
        String password = requestBodyParametersMap.get(passwordParameter);

        if (username == null) {
            username = "";
        }

        if (password == null) {
            password = "";
        }

        username = username.trim();

        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
                username, password);

        // Allow subclasses to set the "details" property
        setDetails(request, authRequest);

        // 交给AuthenticationManager处理
        return this.getAuthenticationManager().authenticate(authRequest);
    }


    /**
     * 获取request body中的json参数数据
     * @param request
     * @return
     */
    private Map<String,String> getRequestBodyJsonParameters(HttpServletRequest request) {
        Map<String ,String> requestBodyParametersMap = new HashMap<>();
        BufferedReader bufferedReader = null;
        StringBuilder stringBuilder = new StringBuilder();
        try {
            bufferedReader = request.getReader();

            if(bufferedReader != null){
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            }
            else {
                stringBuilder.append("");
            }

            String requestBody = stringBuilder.toString();
            if(StringUtils.hasText(requestBody)){
                requestBodyParametersMap = JSON.parseObject(requestBody, Map.class);
            }
        }
        catch (Exception e) {
            log.error("getRequestBodyJsonParameters error", e);
        }

        return requestBodyParametersMap;
    }


    protected void setDetails(HttpServletRequest request,
                              UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }

}
